package com.example.elasticsearch.service;

import com.alibaba.fastjson.JSON;
import com.example.elasticsearch.entity.User;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class EsServiceImpl {

    @Autowired
    RestHighLevelClient restHighLevelClient;

    public boolean createIndex(String idxName){
        try {
            if (this.indexExist(idxName)) {
                System.out.println(idxName+"已存在");;
                return false;
            }
            CreateIndexRequest request = new CreateIndexRequest(idxName);
            CreateIndexResponse res = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            if (!res.isAcknowledged()) {
                return false;
            }
            return true;
        } catch (Exception e) {
            throw new RuntimeException("初始化失败");
        }
    }

    public boolean indexExist(String idxName) throws Exception {
        GetIndexRequest request = new GetIndexRequest(idxName);
        return restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
    }

    public boolean deleteIndex(String idxName) throws Exception {
        if (!this.indexExist(idxName)) {
            System.out.println(idxName+"不存在");;
            return true;
        }
        DeleteIndexRequest request = new DeleteIndexRequest(idxName);
        request.indicesOptions(IndicesOptions.lenientExpandOpen());
        AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        return delete.isAcknowledged();
    }

    public void insertOrUpdateOne(String idxName,User user) {
        IndexRequest request = new IndexRequest(idxName);
        request.id(""+user.getId());
        request.source(JSON.toJSONString(user), XContentType.JSON);

        try {
            restHighLevelClient.index(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void deleteByQuery(String idxName, QueryBuilder queryBuilder) {
        DeleteByQueryRequest request = new DeleteByQueryRequest(idxName);
        request.setQuery(queryBuilder);
        try {
            restHighLevelClient.deleteByQuery(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void insertBatchList(String idxName, List<User> userList) {
        BulkRequest request = new BulkRequest();
        userList.forEach(item -> request.add(new IndexRequest(idxName).id(""+item.getId())
                .source(JSON.toJSONString(item), XContentType.JSON)));
        try {
            restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void deleteByIdList(String idxName, List<String> idList) {
        BulkRequest request = new BulkRequest();
        idList.forEach(item -> request.add(new DeleteRequest(idxName,item)));
        try {
            restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public <T> List<T> search(String idxName, SearchSourceBuilder builder, Class<T> c) {
        SearchRequest request = new SearchRequest(idxName);
        request.source(builder);
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            SearchHit[] hits = response.getHits().getHits();
            List<T> res = new ArrayList<>(hits.length);
            for (SearchHit hit : hits) {
                res.add(JSON.parseObject(hit.getSourceAsString(), c));
            }
            return res;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
